package tt.dz.order.service.rpc;

import java.io.File;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.avro.Protocol;
import org.apache.avro.Protocol.Message;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.ipc.NettyServer;
import org.apache.avro.ipc.Server;
import org.apache.avro.ipc.generic.GenericResponder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;

import tt.dz.order.exception.BusinessException;
import tt.dz.order.service.OrderService;
import tt.dz.order.service.rpc.rpchander.BaseHander;
import tt.dz.order.vo.RetVO;

/**
 * @Title 订单服务器提供的RPC服务
 * @author zhoutian
 * @date 2015-11-17
 */
@Service
public class OrderPRCServer {
	private static Logger log = LoggerFactory.getLogger(OrderPRCServer.class);

	@Autowired
	OrderService orderService;

	@Value(value = "${rpc.self.port}")
	private int port;

	private static Server server;
	private Map<String, String> handerMap = new HashMap<String, String>();

	public OrderPRCServer() {

	}

	@PostConstruct
	public void init() {
		handerMap.put("createOrder", "createOrderHander");
		handerMap.put("modifyOrderStatus", "modifyOrderStatusHander");
		handerMap.put("servicePriceQuery", "servicePriceQueryHander");
		handerMap.put("userPaying", "userPayingHander");
		handerMap.put("unifyAndCorpPay", "unifyAndCorpPayHander");
		handerMap.put("orderHistoryQuery", "orderHistoryQueryHander");
		handerMap.put("findUserNeedPayOrders", "findUserNeedPayOrdersHander");
		handerMap.put("findOrderItemsByOrderNo", "findOrderItemsByOrderNoHander");
		handerMap.put("listOrderServiceInfo", "listOrderServiceInfoHander");
		handerMap.put("queryOrderStatus", "queryOrderStatusHander");
		handerMap.put("advanceCreateOrder", "advanceCreateOrderHander");
		handerMap.put("advanceServicePriceQuery", "advanceServicePriceQueryHander");
		handerMap.put("queryThdPayWayRecordbyOrderNo", "queryThdPayWayRecordbyOrderNoHander");
		handerMap.put("Order2WeiXinOrder", "Order2WeiXinOrderHander");
		handerMap.put("modifyOrderDisplay", "modifyOrderDisplayHander");
		handerMap.put("orderAttach", "orderAttachHander");
		try {
			String filePath = this.getClass().getResource("/orderAvro.json").getPath();
			log.info("orderAvro.json文件路径:" + filePath);
			Protocol protocol = Protocol.parse(new File(filePath));
			server = new NettyServer(new AvroGenericResponder(protocol), new InetSocketAddress(this.port));
			server.start();
		} catch (Exception e) {
			log.info("订单服务器RPC服务初始化失败", e);
		}
	}

	@PreDestroy
	public void closeService() {
		try {
			if (server != null) {
				server.close();
			}
			log.debug("订单服务器rpc接口服务关闭成功");
		} catch (Exception e) {
			log.error("订单服务器rpc接口服务关闭失败", e);
		}
	}

	public class AvroGenericResponder extends GenericResponder {
		public AvroGenericResponder(Protocol protocol) {
			super(protocol);
		}

		@Override
		public Object respond(Message message, Object request) throws Exception {
			log.info("订单服务器接收到RPC请求" + message.getName());
			GenericRecord req = (GenericRecord) request;
			String messageName = message.getName();
			RetVO retVO = new RetVO(RetVO.SuccessCode, null, null);

			try {
				if(handerMap.get(messageName)==null){
					throw new BusinessException("");
				}
				BaseHander baseHander = (BaseHander) ContextLoader.getCurrentWebApplicationContext()
						.getBean(handerMap.get(messageName));
				retVO = baseHander.dohander(req);
				log.debug(messageName+"retVO:"+retVO.toJSONString());
			} catch (Exception e) {
				log.error("获取消息对应处理hander失败", e);
				retVO.setRetCode(RetVO.FailCode);
				retVO.setResultCode("1020300");
				retVO.setErrorMsg("获取消息对应处理hander失败");
			}

			return retVO.toJSONString();
		}

	}
}
